package com.tgy.myredis.service;

import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Date;

/***
 * @ClassName: Service
 * @Description: 测试分布式锁以及controller指定定时任务时间
 * @Auther: tanggy3
 * @Date: 10:22 2022/10/18
 * @version : V1.0
 */
@Slf4j
@PropertySource("classpath:/task-config.ini")
@Service
//@RefreshScope  nacos 的时候动态刷新
public class CornServiceImpl implements SchedulingConfigurer,CornService {

    private final RedissonClient redissonClient;

    public CornServiceImpl(RedissonClient redissonClient) {
        this.redissonClient = redissonClient;
    }


    /**
     * 只使用于固定的定时任务
     */
    @Scheduled(cron = "${printTime.cron}")
    @Override
    @Async
    public void handleFunction() {
        lock("固定");

    }


    @Value("${change.cron}")
    private String cron;

    /**
     * 动态设置定时任务
     *
     * @param taskRegistrar
     */
    @Override
    @Async
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        // 动态使用cron表达式设置循环间隔
        taskRegistrar.addTriggerTask(new Runnable() {
            @Override
            public void run() {
                log.info("Current time： {}", LocalDateTime.now());
                lock("动态");
            }
        }, new Trigger() {
            @Override
            public Date nextExecutionTime(TriggerContext triggerContext) {
                // 使用CronTrigger触发器，可动态修改cron表达式来操作循环规则
                CronTrigger cronTrigger = new CronTrigger(cron);
                Date nextExecutionTime = cronTrigger.nextExecutionTime(triggerContext);
                return nextExecutionTime;
            }
        });


    }

    @Override
    public void lock(String name) {
        String lockName = "lock_name";
        RLock lock = redissonClient.getLock(lockName);
        try {

            log.info("{}获取锁状态{}", name, lock.isLocked());
            if (lock.isLocked() || !lock.tryLock()) {
                log.info("凌晨定时任务没有获得分布式锁！！！不执行定时任务！！！");
                return;
            }


            // 业务代码部分
            log.info("执行定时任务中=========================================================，{}", name);
            Thread.sleep(10000L);

        } catch (InterruptedException e) {
            log.info("lock exception!!!");
        } finally {
            // 最后一定要解锁
            if (lock.isLocked()) {
                lock.unlock();
            }
        }
    }

    @Override
    public void setTime(String cron) {
        this.cron = cron;
    }

    @Override
    public String getCron() {
        return this.cron;
    }
}
